import Event from './event';

class Store {
    constructor(options) {
        this.state = options.state;
        this.observe(this.state);
        this.event = new Event();
        this.actions = options.actions;
    }
    observe(obj) {
        Object.keys(obj).forEach(key => {
            this.defineReactive(obj, key, obj[key]);
        });
    }
    defineReactive(obj, key, value) {
        const that = this;

        Object.defineProperty(obj, key, {
            get() {
                return value;
            },
            set(newValue) {
                value = newValue;
                that.emitUpdate(key);
            }
        });
    }
    emitUpdate(key){
       this.event.emit(key, this.state[key]);
    }
    dispatch(actionName, ...args) {
        if (typeof actionName !== 'string') {
            throw new TypeError(`the action name ${actionName} must be string type`);
        }
        if (Object.keys(this.actions).indexOf(actionName) === -1) {
            throw new Error(`this action name ${actionName} does not exist, please check it`);
        }

        const actionFn = this.actions[actionName];

        // 第一个参数为state
        actionFn.apply(this, [this.state, ...args]);
    }
    onState(key, callback) {
        this.event.on(key, callback);

        // 第一次监听，获取一次数据
        this.emitUpdate(key);
    }
    setState(key, value) {
        this.state[key] = value;
    }
}

export default Store;